import { _decorator, Node, NodeEventType, Sprite, SpriteFrame, UITransform, Vec2 } from 'cc';
import { app } from 'db://app-game/core/app';
import { ViewUtil } from 'db://app-game/core/utils/ViewUtil';
import { ecs } from 'db://app-game/libs/ecs/ECS';
import { CCComp } from 'db://app-game/module/common/CCComp';
import { smc } from '../../../singleton/SingletonModuleComp';
import { SkillButton } from '../SkillButton';

const { ccclass, property } = _decorator;

/** 按钮组件 */
@ccclass('SkillButtonViewComp')
@ecs.register('SkillButtonView', false)
export class SkillButtonViewComp extends CCComp {
  /** 按钮组件实例 */
  skillButton: SkillButton;

  /** 按钮置灰节点 */
  btnGrey: Node;
  btnGreySprite: Sprite;
  /** 按钮遮罩节点 */
  btnMask: Node;
  btnMaskSprite: Sprite;

  /** 冷却时间 */
  cdTimer: number = 0;
  /** 冷却状态 */
  coolingState: boolean = false;

  protected onLoad(): void {
    this.skillButton = this.ent as SkillButton;

    this.init();
  }

  init() {
    // 1.设置按钮图片
    const btnSprite = this.node.addComponent(Sprite);
    btnSprite.spriteFrame = app.res.get(this.skillButton.SkillModel.iconBtnPath, SpriteFrame);

    this.initGrey();
    this.initMask();
    this.initBtnPosSize();
  }

  initGrey() {
    // 1.获取按钮置灰节点 并隐藏
    this.btnGrey = this.node.getChildByName('skill-button-grey');
    this.btnGrey.active = false;
    // 2.设置按钮置灰图片
    this.btnGreySprite = this.btnGrey.addComponent(Sprite);
    this.btnGreySprite.spriteFrame = app.res.get(
      this.skillButton.SkillModel.iconBtnGreyPath,
      SpriteFrame
    );
  }

  initMask() {
    // 1.获取按钮遮罩节点 并隐藏
    this.btnMask = this.node.getChildByName('skill-button-mask');
    this.btnMask.active = false;
    // 2.设置按钮遮罩图片
    this.btnMaskSprite = this.btnMask.getComponent(Sprite);
    this.btnMaskSprite.spriteFrame = app.res.get(
      this.skillButton.SkillModel.iconBtnMaskPath,
      SpriteFrame
    );

    // 3.设置按钮遮罩类型
    this.btnMaskSprite.type = Sprite.Type.FILLED;
    // 4.设置按钮遮罩填充类型
    this.btnMaskSprite.fillType = Sprite.FillType.RADIAL;
    // 5.设置按钮遮罩填充中心
    this.btnMaskSprite.fillCenter = new Vec2(0.5, 0.5);
    // 6.设置按钮遮罩填充起始角度
    this.btnMaskSprite.fillStart = 0;
    // 7.设置按钮遮罩填充范围
    this.btnMaskSprite.fillRange = 1;
  }

  /** 初始化按钮位置/大小 */
  initBtnPosSize() {
    // 1.设置按钮大小
    this.node.getComponent(UITransform).width = this.skillButton.SkillModel.btnSize;
    this.node.getComponent(UITransform).height = this.skillButton.SkillModel.btnSize;

    // 2.设置按钮位置
    ViewUtil.AddWidgetComponent(this.node, this.skillButton.SkillModel.absolutePos);
  }

  protected start(): void {
    // 1.设置冷却时间
    this.cdTimer = 0;
  }

  protected onEnable(): void {
    this.node.on(NodeEventType.TOUCH_START, this.triggerClick, this);
  }
  protected onDisable() {
    this.node.off(NodeEventType.TOUCH_START, this.triggerClick, this);
  }

  /** 点击事件 */
  private triggerClick() {
    // 1.如果冷却状态，则不执行
    if (this.coolingState) return;
    // 2.触发技能
    const sm = this.skillButton.SkillModel;
    const isRelease = smc.account.AccountModel.role.roleSkillRelease({
      skillId: sm.id,
      skillLevel: sm.level,
    });
    // 3.如果技能释放成功，则过度到技能冷却
    if (!isRelease && sm.cdTime > 0) this.transitionToCooling();
  }

  /** 过度到技能冷却 */
  private transitionToCooling() {
    // 1.技能冷却状态启动
    this.coolingState = true;

    // 2.技能冷却遮罩启动
    this.btnMask.active = true;
    // 3.技能冷却重新计时
    this.cdTimer = this.skillButton.SkillModel.cdTime;
  }

  /** 技能冷却更新 */
  private coolingUpdate(dt: number) {
    // 1.冷却时间减少
    this.cdTimer -= dt;

    // 2.设置冷却遮罩填充范围
    this.btnMaskSprite.fillRange = this.cdTimer / this.skillButton.SkillModel.cdTime;

    // 3.如果冷却时间结束，则关闭冷却状态
    if (this.cdTimer <= 0) {
      // 1.关闭冷却状态
      this.coolingState = false;
      // 2.关闭冷却遮罩
      this.btnMask.active = false;
    }
  }

  /** 判断按钮是否缺失释放技能的条件 */
  private checkReleaseCost() {
    // 1.获取按钮释放条件
    const releaseCost = this.skillButton.SkillModel.releaseCost;
    const keys = Object.keys(releaseCost);
    if (keys.length === 0) return true;
    // 2.判断按钮是否缺失释放技能的条件
    const rm = smc.account.AccountModel.role.RoleModel;
    return keys.every(key => {
      if (key === 'hp') {
        if (rm.chp <= releaseCost.hp) {
          return false;
        }
      }
      if (key === 'mp') {
        if (rm.cmp <= releaseCost.mp) {
          return false;
        }
      }
      return true;
    });
  }

  protected update(dt: number): void {
    // 1.动态刷新冷却时间
    if (this.coolingState) this.coolingUpdate(dt);

    // 2.判断按钮是否缺失释放技能的条件
    const isReleaseCost = this.checkReleaseCost();

    // 3.设置按钮置灰状态
    if (isReleaseCost) {
      this.btnGrey.active = true;
    } else {
      this.btnGrey.active = false;
    }
  }

  reset(ent: ecs.Entity): void {
    this.node.destroy();
  }
}
